Over the past few posts, we have laid out several JavaScript best practices that can be used to produce maintainable web applications using JavaScript. While the number of options can be overwhelming, there are many JavaScript tools you can use to automate these practices or simplify common development tasks.
JavaScript Tools: Package Managers
Dependency management is one of the most useful features in a development workflow. By centralizing dependency management, it is therefore much easier for a development team to maintain a stable and consistent environment. Popular dependency management tools are available for other languages as well, such as Maven for Java and NuGet for .NET. As far as JavaScript tools go, JavaScript has several package managers. The most noteworthy of these is NPM.
NPM
NPM is one of the most important JavaScript tools in modern JavaScript development. It is bundled with Node.js and allows you to install and manage dependencies from either the NPM registry or any Git repository. While developed for Node.js, you can use NPM in any application whether Node is used or not. NPM uses the package.json file and semantic versioning (semver) conventions to manage both runtime and development dependencies. You can add modules to the application using the npm command, and they are saved to the node_modules directory.
npm install ## Install without saving to package.json
npm install --save ## Install and save a runtime dependency
npm install --save-dev ## Install and save a development dependency
While NPN is by far the most popular package manager for JavaScript applications, there are several alternatives for comparison. Bower bills itself as the package manager for the web. It can manage dependencies of JavaScript, CSS, fonts, or even images. Bower is installed with NPM and saves its configuration in the bower.json file. Installed packages are saved to the bower_components directory in a flat dependency structure.
npm install -g bower ## Install the bower app globally using npm
bower install ## Install bower package without saving to bower.json
bower install --save ## Install and save a bower package
JSPM
JSPM is a newer, powerful package manager. It combines several of the features of both NPM and Bower. JSPM uses a flat dependency structure and can install non-JS assets like Bower. Yet, it installs to package.json and uses a central registry, like NPM. JSPM is built around the System.js module loader and works seamlessly with both Babel and TypeScript transpilers.
npm install -g jspm ## Install the jspm app globally using npm
jspm install ## Install package from jspm registry
jspm install npm: ## Install package from the npm registry
jspm install github: ## Install package from Github
In my experience, NPM is one of the most essential JavaScript tools for modern JavaScript development. As you can see by the previous code examples, both Bower and JSPM are installed using NPM. Because of its pervasiveness and large repository, I always use and recommend NPM for managing JavaScript dependencies.
JavaScript Build Tools
Automation of common development tasks is necessary to ensure consistent output from the written source code. Build tools have existed for years in other programming languages and environments, such as Ant, Maven, and Gradle for Java or make the class Unix build tool. While it’s possible to write JavaScript without any build steps, using the following build tools will allow you to integrate many different JavaScript tools into the development workflow, such as linters and testing. With the capability to watch for file changes, these JavaScript build tools can automatically perform multiple tasks on each file save, which not only speeds up development, but also can ensure that tests are passing and automatically redeploy the application for instant feedback using Live Reload.
Grunt
Grunt is a JavaScript task runner like Ant for Java. It uses plugins configured by using a JSON syntax in a Gruntfile. Grunt plugins simply take in an input file or directory and output another file modified by the plugin. One of the main downsides of Grunt is the generation of temporary files for each step of the build process. For instance, if you want to bundle multiple JavaScript files into one minified output file, Grunt would need to first create an unminified bundle file that can then be passed to another plugin to create the minified file.
npm install -g grunt
grunt
Gulp
Gulp is a JavaScript task runner based on the concept of streams. Like Grunt, repetitive tasks are automated. However, instead of configuring the tasks in a Gruntfile, the tasks are simply code that takes files in as streams and passing through any number of steps until writing files to an output directory. Unlike Grunt, all processing of the files is done in memory and only the final files are written to disk.
npm install -g gulp
gulp
Broccoli
Broccoli is an asset pipeline for JavaScript applications similar to the Rails asset pipeline for Ruby on Rails applications. It is also heavily used by the Ember.js community. It allows for very fast incremental builds.
npm install -g broccoli-cli
npm install --save-dev broccoli
broccoli build
Webpack
Webpack is a bundler for all front-end assets, including JavaScript. The main purpose is to bundle multiple files for use in the browser. Webpack also allows for more advanced bundling, such as incremental builds and asynchronous loading.
npm install -g webpack
webpack
While all of these JavaScript build tools have their strengths, I currently use Gulp for most JavaScript projects. Because of its speed, large plugin library and ease of customization I find Gulp to be a great general use build tool.
JavaScript Static Analysis
As we previously discussed, creating team JavaScript coding standards is an important way to create a more maintainable code base. You can use the following JavaScript static analysis tools to enforce the rules that the team sets in place.
JSLint
JSLint was written by Douglas Crockford to enforce the rules in his book, JavaScript: the Good Parts. It was the first popular JavaScript linter and is useful, yet limited in its customizability.
npm install -g jslint
JSHint
JSHint is a fork of JSLint that allows for more customization to override many of Crockford’s rules, if so desired.
npm install -g jshint
ESLint
ESLint is a JavaScript linter that is similar to JSHint, but built around packages for extensibility. Instead of configuring each app individually, you can simply install the ESLint package for many common frameworks and applications. In Angular, for example, this can ensure your application follows the guidelines for Angular best practices created by the community.
npm install -g eslint
npm install --save-dev eslint-plugin-angular
npm install --save-dev eslint-config-angular
JSCS
JSCS is a style checker. You can use it to enforce strict guidelines on the format of JavaScript files. Once the development team decides on a desired pattern, you can use JSCS to ensure those coding standards are followed. If you have ever wanted to guarantee that all if statements have a space between the if and the parentheses or that array elements are separated by both commas and spaces, then JSCS is the tool for you.
npm install -g jscs
I currently use a combination of JSHint and JSCS for JavaScript static analysis tasks. When you combine the two JavaScript tools, it’s possible to cover most JavaScript coding standards and rules. Recently, the JSCS and ESLint teams announced a collaboration between the two projects. So, I may start using ESLint more in the future if it can provide the functionality of both JavaScript tools in a single package.
CSS Preprocessors
While we’ve mostly focused on JavaScript in this series, there are several CSS preprocessors that can add many features that aren’t included in standard CSS, such as variables, nesting, and functions that will enable more manageable CSS styling.
Sass
Sass is the most popular CSS processor and provides the largest feature set and popular extensions, such as Compass and Bourbon. It uses either a Ruby library or a slower NodeJS package to process the SCSS files. It provides an easy way to use variables to quickly change styles and nesting to more clearly organize stylesheets.
$primary-color: blue;
nav {
color: $primary-color;
ul {
list-style: none;
}
}
Less
Less is similar to Sass, but also allows for real-time compilation by the browser, which can speed up development by eliminating a build step. While Less was popular for many years and remains in active use, many projects are migrating to Sass.
@primary-color: blue;
nav {
color: @primary-color;
ul {
list-style: none;
}
}
PostCSS
PostCSS is a newer CSS processor and uses JavaScript plugins to transform the CSS. Because of this, PostCSS is much smaller than the other preprocessors on initial install, and more powerful features are added by installing individual plugins as needed. As a pure JavaScript solution, PostCSS is an intriguing option. There are plugins to perform pretty much every task that can be accomplished by Sass or Less, including the ability to change syntax to match Sass, while also having the option to write your own plugins using standard JavaScript to handle any custom operations. Additionally, you can use PostCSS as either a preprocessor, like Sass or Less, and as a post-processor to manipulate CSS to include functionality such as browser vendor prefixes to improve cross-browser compatability. This allows you to use PostCSS on existing CSS stylesheets and also on stylesheets generated by either Sass or Less.
While Sass is much more popular, I currently use and recommend PostCSS. This is because its modular approach and pure JavaScript nature make PostCSS a lightweight and customizable solution for CSS preprocessing.
Stay tuned for Angular UI Router Modals…
In conclusion, these JavaScript tools: package managers, build tools, static analysis tools and CSS preprocessors are helpful in automating or simplifying common development tasks to utilize JavaScript best practices in producing maintainable web applications. In our final blog post of this series, we will discuss a technique that I use to integrate Bootstrap modals into Angular applications using UI Router.